﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using XRpgLibrary;
using XRpgLibrary.Controls;
using XRpgLibrary.ScriptClasses;
using XRpgLibrary.CharacterClasses;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace SourceOfMagic.GameScreens
{
    public abstract partial class BaseGameState : GameState
    {
        #region Fields region
        
        protected SourceOfMagicGame GameRef;
        protected ControlManager ControlManager;
        protected PlayerIndex playerIndexInControl;

        protected BaseGameState TransitionTo;

        protected bool Transitioning;
        
        protected ChangeType changeType;
        
        protected TimeSpan transitionTimer;
        protected TimeSpan transitionInterval = TimeSpan.FromSeconds(0.5);

        private SpriteFont menuFont;

        private List<IGameDrawable> drawList;
        private List<IGameDrawableMenu> drawMenuList;
        private List<IGameUpdateable> updateList;
        private List<IGameUpdateableMenu> updateMenuList;

        protected ScriptContext scriptContext;
        #endregion
        
        #region Properties region

        
        protected List<IGameDrawable> DrawList
        {
            get
            {
                if (drawList == null)
                    drawList = new List<IGameDrawable>();

                return drawList;
            }
            set
            {
                drawList = value;
            }
        }

        protected List<IGameDrawableMenu> DrawMenuList
        {
            get
            {
                if (drawMenuList == null)
                    drawMenuList = new List<IGameDrawableMenu>();

                return drawMenuList;
            }
            set
            {
                drawMenuList = value;
            }
        }

        protected List<IGameUpdateable> UpdateList
        {
            get
            {
                if (updateList == null)
                    updateList = new List<IGameUpdateable>();

                return updateList;
            }
            set
            {
                updateList = value;
            }
        }

        protected List<IGameUpdateableMenu> UpdateMenuList
        {
            get
            {
                if (updateMenuList == null)
                    updateMenuList = new List<IGameUpdateableMenu>();

                return updateMenuList;
            }
            set
            {
                updateMenuList = value;
            }
        }

        protected SpriteFont MenuFont
        {
            get
            {
                if (menuFont == null)
                    menuFont = Game.Content.Load<SpriteFont>(@"Fonts\ControlFont");

                return menuFont;
            }
        }

        #endregion
        
        #region Constructor Region
        
        public BaseGameState(RpgGame game, GameStateManager manager)
            : base(game, manager)
        {
            GameRef = (SourceOfMagicGame)game;
            playerIndexInControl = PlayerIndex.One;
            scriptContext = new ScriptContext(
                game, 
                GamePlayScreen.Engine, 
                GamePlayScreen.World, 
                GamePlayScreen.Player);
        }
        
        #endregion

        public override void Initialize()
        {
            base.Initialize();
        }

        #region XNA Method Region
        protected override void LoadContent()
        {
            ControlManager = new ControlManager(MenuFont);
            
            base.LoadContent();
        }

        public override void Update(GameTime gameTime)
        {
            if (Transitioning)
            {
                transitionTimer += gameTime.ElapsedGameTime;

                if (transitionTimer >= transitionInterval)
                {
                    Transitioning = false;
                    switch (changeType)
                    {
                        case ChangeType.Change:
                            StateManager.ChangeState(TransitionTo);
                            break;
                        case ChangeType.Pop:
                            StateManager.PopState();
                            break;
                        case ChangeType.Push:
                            StateManager.PushState(TransitionTo);
                            break;
                    }
                }
            }

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);
        }

        #endregion

        #region Method Region

        public virtual void Transition(ChangeType change, BaseGameState gameState)
        {
            Transitioning = true;
            changeType = change;
            TransitionTo = gameState;
            transitionTimer = TimeSpan.Zero;
        }

        public virtual void TransitionChange(BaseGameState gameState)
        {
            Transition(ChangeType.Change, gameState);
        }

        public virtual void TransitionPush(BaseGameState gameState)
        {
            Transition(ChangeType.Push, gameState);
        }

        public virtual void TransitionPop()
        {
            Transition(ChangeType.Pop, null);
        }


        #endregion

    }
}